package com.wr.service.impl;

import com.google.common.collect.ImmutableMap;
import com.wr.Exception.UserException;
import com.wr.mapper.UserMapper;
import com.wr.model.User;
import com.wr.service.MailService;
import com.wr.service.UserService;
import com.wr.utils.HashUtils;
import com.wr.utils.JwtHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author weirong
 * @Title:
 * @Description:
 * @date 2018/6/511:41
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    MailService mailService;
    @Autowired
    RedisTemplate redisTemplate;

    public int deleteByPrimaryKey(Integer id) {
        return userMapper.deleteByPrimaryKey(id);
    }

    public int insertSelective(User record) {
        record.setPassword(HashUtils.encryPassword(record.getPassword()));
         userMapper.insertSelective(record);
        return record.getId();
    }

    public User selectByPrimaryKey(Integer id) {
        return userMapper.selectByPrimaryKey(id);
    }

    public int updateByPrimaryKeySelective(User record) {
        return userMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public User getByEmail(String email) {
        return userMapper.getByEmail(email);
    }

    @Override
    public User getUserByUserName(String username) {
        return userMapper.getUserByUserName(username);
    }


    /**
     * 校验用户名密码、生成token并返回用户对象
     * @return
     */
    public User authLogin(User user) {
        if (StringUtils.isBlank(user.getEmail()) || StringUtils.isBlank(user.getPassword())) {
            throw new UserException(UserException.Type.USER_AUTH_FAIL,"User Auth Fail");
        }
        user.setPassword(HashUtils.encryPassword(user.getPassword()));
        user.setStatus((byte) 1);
        User u =  userMapper.authLogin(user);
        if (u != null) {
            onLogin(u);
            return u;
        }
        throw new UserException(UserException.Type.USER_AUTH_FAIL,"User Auth Fail");
    }

    private void onLogin(User user) {
        String token =  JwtHelper.genToken(ImmutableMap.of("email", user.getEmail(), "name", user.getUsername(),"id", String.valueOf(user.getId()),"ts", Instant.now().getEpochSecond()+""));
        renewToken(token,user.getEmail());
        user.setToken(token);
    }

    private String renewToken(String token, String email) {
        redisTemplate.opsForValue().set(email, token);
        redisTemplate.expire(email, 30, TimeUnit.MINUTES);
        return token;
    }

    public User getLoginedUserByToken(String token) throws Exception {
        Map<String, String> map = null;
        try {
            map = JwtHelper.verifyToken(token);
        } catch (Exception e) {
            throw new Exception("token校验失败",e);
        }
        String email =  map.get("email");
        Long expired = redisTemplate.getExpire(email);
        if (expired > 0L) {
            renewToken(token, email);
            User user = getByEmail(email);
            user.setToken(token);
            return user;
        }
        return null;

    }

    @Override
    public void logout(String token) {
        Map<String,String> map = JwtHelper.verifyToken(token);

        redisTemplate.delete(map.get("email"));
    }

    @Override
    public void resetPw(User user) {
        user.setPassword(HashUtils.encryPassword(user.getPassword()));

        userMapper.updateByPrimaryKeySelective(user);
    }


}
